/**
 * 
 */
package info.niwota.webshot.imglist;

import info.niwota.webshot.Debug;
import info.niwota.webshot.FileItem;
import info.niwota.webshot.StatusMonitor;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class FileList implements IImageList, Serializable {

	private static final long serialVersionUID = 1L;
	
	private class FileItemComparator implements Comparator<FileItem>, Serializable {
		private static final long serialVersionUID = 1L;
		
		public int compare(FileItem o1, FileItem o2) {

			if (o1 == null) {
				return -1;
			}
			if (o2 == null) {
				return 1;
			}
			if (o1.modified > o2.modified) {
				return -1;
			}
			if (o1.modified < o2.modified) {
				return 1;
			}
			return 0;
		}

	}
	
	public class MyImage implements IImage {

		private FileItem entry;

		private Bitmap bitmap;

		private File file;

		private Uri imageUri;

		public MyImage(FileItem entry) {
			this.entry = entry;
			//
			String p = entry.getName(); //absolute
			this.file = new File(p);
			
			this.imageUri = Uri.fromFile(file);
			if (Debug.DEBUG) {
				Log.d(TAG, "image uri: " + imageUri);
			}
		}

		public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels) {
			return fullSizeBitmap(minSideLength, maxNumberOfPixels, false,
					false);
		}

		public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels,
				boolean rotateAsNeeded, boolean useNative) {
			if (Debug.DEBUG) {
				Log.d(TAG, "fullSizeBitmap: " + entry.getName() + " bitmap: "
						+ bitmap);
			}
			try {
				if (bitmap != null) {
					return bitmap;
				}
				ParcelFileDescriptor fd = open();
				bitmap = Util.makeBitmap(minSideLength, maxNumberOfPixels, fd,
						null);
				//
				return bitmap;
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}

		private ParcelFileDescriptor open() {
			try {
				ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
						ParcelFileDescriptor.MODE_READ_ONLY);
				return fd;
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			return null;
		}

		public long fullSizeImageId() {
			return 0;
		}

		public Uri fullSizeImageUri() {
			return imageUri;
		}

		public long getDateTaken() {
			return 0;
		}

		public int getDegreesRotated() {
			return 0;
		}

		public String getDisplayName() {
			return null;
		}

		public int getHeight() {
			return 0;
		}

		public String getMimeType() {
			return null;
		}

		public String getTitle() {
			return null;
		}

		public int getWidth() {
			return 0;
		}

		public Bitmap miniThumbBitmap() {
			if (Debug.DEBUG) {
				Log.d(TAG, "miniThumbBitmap: " + entry.getName());
			}
			return thumbBitmap(IImage.ROTATE_AS_NEEDED);
		}

		public boolean rotateImageBy(int degrees) {
			return false;
		}

		public Bitmap thumbBitmap(boolean rotateAsNeeded) {
			return fullSizeBitmap(THUMBNAIL_TARGET_SIZE,
					THUMBNAIL_MAX_NUM_PIXELS);
		}
	}

	private static final String TAG = "FileList";

	private ArrayList<FileItem> list;

	private Uri base;

	public FileList() {
	}

	public void load(Context ctx, Uri base, StatusMonitor status)
			throws Exception {
		if (list != null) {
			return;
		}
		this.base = base;
		this.list = new ArrayList<FileItem>();
		//
		if (Debug.DEBUG) {
			Log.d(TAG, "FileList base: " + base);
		}
		// load
		if (!base.getScheme().equals("file")) {
			throw new IOException("Not supported " + base.getScheme());
		}
		File file = new File(base.getPath());
		File[] fl = file.listFiles(new FilenameFilter() {
			public boolean accept(File dir, String name) {
				return (name.endsWith(".jpg") || name.endsWith(".png") || name.endsWith(".gif"));
			}
		});
		if (fl == null) {
			return;
		}
		for (int i = 0; i < fl.length; i++) {
			File f = fl[i];
			FileItem fi = new FileItem(f.getPath());
			fi.setModified(f.lastModified());
			fi.setSize(f.length());
			
			list.add(fi);
		}
		FileItemComparator c = new FileItemComparator();
		Collections.sort(list, c);
	}

	public void close() {
		if (list != null) {
			list.clear();
			list = null;
		}
	}

	public int getCount() {
		return (list == null ? 0 : list.size());
	}

	public FileItem getItem(int i) {
		if (Debug.DEBUG) {
			Log.d(TAG, "getItem: " + i);
		}
		if (list == null) {
			return null;
		}
		FileItem fi = list.get(i);
		return fi;
	}

	public IImage getImageAt(int i) {
		if (Debug.DEBUG) {
			Log.d(TAG, "getImageAt: " + i);
		}
		if (list == null) {
			return null;
		}
		FileItem fi = list.get(i);

		if (Debug.DEBUG) {
			Log.d(TAG, "getImageAt: " + fi.getName());
		}

		return new MyImage(fi);
	}

	public boolean isEmpty() {
		return (list == null || list.size() == 0);
	}

	public boolean removeImageAt(int i) {
		return false;
	}

	public void saveState(Bundle b) {
		b.putParcelable("base", base);
		b.putSerializable("list", list);
	}

	@SuppressWarnings("unchecked")
	public void restoreState(Bundle b) {
		ArrayList<FileItem> serializable = (ArrayList<FileItem>) b
				.getSerializable("list");
		list = serializable;
		base = (Uri) b.getParcelable("base");
	}
}
